package mpbe.estructura.secciones.hormigon_armado.contornos;

/*
 * Este codigo es software libre y se encuentra licenciado 
 * bajo los términos de la Licencia Pública General de GNU versión 3 
 * según se encuentra publicada por la Free Software Foundation.
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Autor: Martin Pablo Bellanca <martin.bellanca@gmail.com>
 * web: http://mpbe.blogspot.com/
 */

import java.util.Vector;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import com.sun.script.javascript.JSAdapter;

import mpbe.estructura.secciones.hormigon_armado.graficos.SHDibujar;
import mpbe.geometria.Parametro;
import mpbe.geometria.Poligono;
import mpbe.geometria.Punto;


/**
 * @author  mpbe
 */
public class SHContorno {
	public boolean activo;
	public String designacion;
	//public String tipo;
	//public Vector<Parametro> parametros;
	public Vector<Punto> nodos;
	/**
	 * @uml.property  name="parametros"
	 * @uml.associationEnd  
	 */
	public SHContornoPorParametros parametros;
	/**
	 * @uml.property  name="tiposDeContornos"
	 * @uml.associationEnd  
	 */
	public static SHTiposDeContornos tiposDeContornos= new SHTiposDeContornos();
	
	public String archivo;
	
	public SHContorno() {
		inicialize(false, "hueco", new SHContornoRectangular(), new Vector<Punto>());
	}
	public SHContorno(boolean activo, String designacion, SHContornoPorParametros parametros, Vector<Punto> nodos){
		inicialize(activo, designacion, parametros, nodos);
	}
	public SHContorno(boolean activo){
		inicialize(activo, "Hueco", new SHContornoRectangular(), new Vector<Punto>());
	}
	
	public SHContorno(boolean activo, String designacion){
		inicialize(activo, designacion, new SHContornoRectangular(), new Vector<Punto>());
	}
	
	private void inicialize(boolean activo, String designacion, SHContornoPorParametros parametros, Vector<Punto> nodos) {
		//tiposDeContornos = new SHTiposDeContornos();
		
		this.activo = activo;
		this.designacion = designacion;
		//this.tipo = tipo;
		this.parametros = parametros;
		this.nodos = nodos;
		if (nodos.size()==0) {
			nodos.add(new Punto(-10,25));
			nodos.add(new Punto(10,25));
			nodos.add(new Punto(10,-25));
			nodos.add(new Punto(-10,-25));
		}
		
		/*// TODO PARA PRUEBAS, SACAR
		if (parametros.size()==0) {
			parametros.add(new Parametro("prueba param1", 10, 5));
			parametros.add(new Parametro("prueba param2", 20, 6));
		}*/
	}
	
	public void setContorno(boolean activo, String designacion, String tipo, SHContornoPorParametros parametros, Vector<Punto> nodos){
		this.activo = activo;
		this.designacion = designacion;
		//this.tipo = tipo;
		this.parametros = parametros;
		this.nodos = nodos;
	}
	public void setContorno(SHContorno contorno) {
		this.activo = contorno.activo;
		this.designacion = contorno.designacion;
		//this.tipo = contorno.tipo;
		this.parametros = contorno.parametros;
		this.nodos = contorno.nodos;
	}
	public SHContorno getContorno() {
		return this;
	}
	
	public void copyInto(SHContorno contorno) {
		contorno.activo = activo;
		contorno.designacion = designacion.toString();
		//contorno.tipo = tipo;
		
		contorno.parametros = parametros.getNewParametro();
		Parametro par;
		Parametro par1;
		for (int ii=0; ii<10; ii++) {
			par = parametros.getParametro(ii);
			par1 = contorno.parametros.getParametro(ii);
			par1.valor = par.valor;
		}
		
		Punto pp;
		Punto pp1;
		contorno.nodos.clear();
		for (int ii=0; ii<nodos.size(); ii++) {
			pp = nodos.get(ii);
			pp1 = new Punto();
			pp.copyInto(pp1);
			contorno.nodos.add(pp1);
		}
	}
	
	//********************************
	//Funciones de modificacion
	//********************************
	public void mod_InvertirV(){
		Punto nodo;
		for (int ii=0; ii<nodos.size(); ii++){
			nodo = nodos.get(ii);
		    nodo.Y *= -1;
		}
		parametros = new SHContornoNone();
	}
	
	public void mover(double deltaX, double deltaY){
		Punto nodo;
		for (int ii=0; ii<nodos.size(); ii++){
			nodo = nodos.get(ii);
			nodo.X += deltaX;
			nodo.Y += deltaY;
		}
	}
	
	public void rotar(double grados){
		double rad, l;
		double delta = grados*Math.PI/180;
		Punto nodo;
		for (int ii=0; ii<nodos.size(); ii++){
			nodo = nodos.get(ii);
			l = Math.sqrt(nodo.X*nodo.X+nodo.Y*nodo.Y);
			rad = Math.atan2(nodo.Y, nodo.X);
			rad += delta;
			nodo.X = Math.cos(rad)*l;
			nodo.Y = Math.sin(rad)*l;
		}
	}
	
//	public void offset(double distancia) {
//		double tga = 0;
//		double hpa = 0;
//		
//		Punto P1p = new Punto();
//		Punto P1 = nodos.get(0); //punto inicial
//		Punto P2 = nodos.get(1); //punto final
//		
//		double Vx = P2.X - P1.X; //vector direccion X
//		double Vy = P2.Y - P1.Y; //vector direccion Y
//		double R = Math.sqrt(Vx*Vx+Vy*Vy);
//		// coeficientes de la recta A*X+B*Y+C=0
////		double A = 1/Vx;
////		double B = -1/Vy;
////		double C = -(P1.X/Vx+P1.Y/Vy);
//		
//		// rotar V 90grad en sentido horario para obtener el vector direccion del offset
//		// tener en cuenta el signo de distancia (- es hacia adentro y +hacia afuera)
//		
//		// calcula coef de la recta Y = tg(rad)*X+h
//		double tg = Vy/Vx;
//		double h = P2.Y-tg*P2.X;
//		
//		// calcula los coef de la recta paralela a la distancia dadda
//		// la ecuacion de la recta paralela queda dada por Y = X*Tg(rad) + hp
//		//double rad = Math.atan2(Vy, Vx); //angulo de la recta en rad
//		double cos = Vy/R/tg;
//		double Yh = cos*distancia; //Ver que pasa aca con el signo de distancia
//		double hp = h + Yh;
//		
//		// el nudo final se corre a la interseccion de las 2 rectas paralelas
//		P1p.X = (hp-hpa)/(tga-tg);
//		P1p.Y = tg*P1p.X+hp;
//		
//		
//	}
	
	public int [] getPolygon (){
		Punto nodo;
		int con = 0;
		int [] res = new int[nodos.size()*2];
		for (int ii=0; ii<nodos.size(); ii++){
			nodo = nodos.get(ii);
			res[con++] = (int)nodo.X;
			res[con++] = (int)nodo.Y;
		}
		return res;
	}
	public Poligono getPolygon1() {
		Poligono res = new Poligono();
		Punto nodo;
		for (int ii=0; ii<nodos.size(); ii++){
			nodo = nodos.get(ii);
			res.add(nodo);
			
		}
		return res;
	}
	
	
	public int [] getPolygon (double deltaX, double deltaY, int corrimientoX, int corrimientoY, double escalaX, double escalaY){
		Punto nodo;
		int con = 0;
		int [] res = new int[nodos.size()*2];
		double Aux;
		for (int ii=0; ii<nodos.size(); ii++){
			nodo = nodos.get(ii);
			if (nodo.X>0) 
				Aux = nodo.X-deltaX;
			else if (nodo.X<0)
				Aux = nodo.X+deltaX;
			else 
				Aux = nodo.X;
			res[con++] = (int)(SHDibujar.transformar(Aux, corrimientoX, escalaX));
//			res[con++] = (int)Aux;
			
			if (nodo.Y>0) 
				Aux = nodo.Y-deltaY;
			else if (nodo.Y<0)
				Aux = nodo.Y+deltaY;
			else 
				Aux = nodo.Y;
			res[con++] = (int)(SHDibujar.transformar(Aux, corrimientoY, escalaY));
//			res[con++] = (int)Aux;
		}
		return res;
	}
	//*****************************************************
	// Funciones JSON
	//*****************************************************
	public void put_JSON(JSONObject jo){
		activo = (Boolean) jo.get("Activo");
		designacion = (String) jo.get("Designacion");
		
		JSONObject joParametros = (JSONObject) jo.get("Parametros");
		parametros = new SHContornoPorParametros();  //OJO con esta instruccion
		parametros.designacion = (String) joParametros.get("Designacion");
		//SHContorno.tiposDeContornos.load_Contornos();
		parametros = SHContorno.tiposDeContornos.getTipo(parametros.designacion);
		/*for (int ii=0; ii<joParametros.size(); ii++){
			parametros.parametros[ii].valor = (Double) joParametros.get(parametros.parametros[ii].designacion);
		}*/
		int ii = 0;
		while (parametros.parametros[ii].designacion !="fin") {
			parametros.parametros[ii].valor = (Double) joParametros.get(parametros.parametros[ii].designacion);
			ii++;
		} 

		JSONArray jsNodos = (JSONArray) jo.get("Nodos");
		nodos.clear();
		Punto pp1;
		for (int jj=0; jj<jsNodos.size(); jj++) {
			pp1 = new Punto();
			pp1.put_JSON((JSONObject) jsNodos.get(jj)); //***** REVISAR ESTO
			nodos.add(pp1);
		}
	}
	public JSONObject get_JSONObject() {
		JSONObject jo = new JSONObject();
		jo.put("Activo",activo);
		jo.put("Designacion", designacion);
		
		JSONObject joParametros = parametros.get_JSONObject();
		jo.put("Parametros", joParametros);
		
		JSONArray jsNodos = new JSONArray();
		for (int jj=0; jj<nodos.size(); jj++) {
			jsNodos.add(nodos.get(jj));
		}
		jo.put("Nodos", jsNodos);
		return jo;
	}
	public String get_JSONString(int tab) {
		String res = tabs(tab)+"{\n";
		res += tabs(tab+1)+"\"Activo\":"+activo+",\n";
		res += tabs(tab+1)+"\"Designacion\":\""+designacion+"\",\n";
		res += tabs(tab+1)+"\"Parametros\":"+parametros.get_JSONString(tab+1)+",\n";
		
		res += tabs(tab+1)+"\"Nodos\":[\n";
		Punto pp = new Punto();
		for (int jj=0; jj<nodos.size(); jj++) {
			pp = nodos.get(jj);
			res += tabs(tab+2)+pp.get_JSONString()+",\n";
		}
		res += tabs(tab+1)+"]\n";
		res += tabs(tab)+"}";		
		return res;
	}
	private String tabs(int can) {
		String str = new String();
		for (int ii=0; ii<can; ii++) str += "   ";
		return str;
	}
	
}
